<?php

namespace app\index\service;

use app\common\model\Trade;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\traits\TradeShareEstimateTrait;
use think\exception\ValidateException;
use think\facade\Config;

/**
 * Class TradeSourceService
 * @package app\index\service
 */
class TradeSourceService implements TradableInterface
{
    use TradeShareEstimateTrait;

    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 通话后，追加案源订单
     * @param $memberId
     * @param $sourceId
     * @param $num
     * @param $price
     * @param $axbRecord
     * @param $source
     * @return Trade
     */
    public function append($memberId, $sourceId, $num, $price, $axbRecord, $source): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_SOURCE;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $source_type = $source ? $source['source_type'] : '';

        $aryOrderId = null;
        if (is_array($axbRecord) && isset($axbRecord['orderId'])) {
            $aryOrderId = $axbRecord['orderId'];
        }

        if (is_blank($sourceId)) {
            throw new ValidateException('请选择一个案源');
        }

        $describe = $tradeConfig['name'];

        if (!is_numeric($num)) {
            throw new ValidateException('该案源不能购买');
        }

        if (!is_numeric($price) || $price < 1) {
            throw new ValidateException('该案源不能购买');
        }

        // 暂时没说优惠卷
        $showMoney = $price;
        $totalMoney = $price;
        $payMoney = $totalMoney;

        if ($payMoney < 0.01) {
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'payMethod' => PAYMENT_CARD,
            'memberId' => $memberId,
            'orderNoPre' => 'S',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'sourceId' => $sourceId,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'num' => $num,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => Trade::NOTSETTLE,
            'sourceStatus' => Trade::ARY_INVITING,
            'attach' => [
                'attach' => '',
                'record' => $axbRecord,
                'aryOrderId' => $aryOrderId,
                'source' => $source,
                'source_type' => $source_type,
                'buyout' => '0',
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建事件
        event('TradeCreated', $record);

        return $record;
    }


    /**
     * 案源订单-买断
     * @param UM $user
     * @param Trade $trade 原订单
     * @param array $params 请求数据
     * @param array $source 案源信息
     * @return Trade
     */
    public function buyout(UM $user, Trade $trade, array $params, array $source): Trade
    {
        $tradeType = TRADE_SOURCE;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $memberId = $user->id;

        $sourceId = $trade->sourceId;
        $describe = $trade->describe;
        $originTradeId = $trade->id;

        $totalNum = $source['total_num'] ?? null;
        $soldNum = $source['sold_num'] ?? null;
        $unitPrice = $source['unit_price'] ?? null;

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        // 推广回传
        $promotionFeedback = $params['promotionFeedback'] ?? null;

        $num = $totalNum - $soldNum;

        // 计算价格
        $price = bcmul($unitPrice, $num, 2);

        if (!is_numeric($num) || $num < 1 || !is_numeric($price) || $price < 1) {
            throw new ValidateException('该案源不能购买');
        }

        // 暂时没说优惠卷
        $showMoney = $price;
        $totalMoney = $price;
        $payMoney = $totalMoney;

        $tradeParams = [
            // 获客卡支付
            'payMethod' => PAYMENT_CARD,
            'memberId' => $memberId,
            'orderNoPre' => 'S',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'sourceId' => $sourceId,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'num' => $num,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => Trade::NOTSETTLE,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
                'originTradeId' => $originTradeId,
                'source' => $source,
                'source_type' => $source['source_type'],
                'buyout' => '1',
                'promotionFeedback' => $promotionFeedback,
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建事件
        event('TradeCreated', $record);

        return $record;
    }

    /**
     * 案源订单-直接拨打-购买
     * @return void
     */
    public function buy(UM $user, array $params, array $source): Trade
    {
        // 补齐参数，创建Trade
        $tradeType = TRADE_SOURCE;
        $tradeConfig = Config::get("trade.trades.$tradeType", []);
        $tradeTypeClass = $tradeConfig['className'] ?? '';

        $memberId = $user->id;

        $source_type = $source['source_type'] ?? '';
        $sourceId = $source['source_id'] ?? '';

        $aryOrderId = $params['aryOrderId'] ?? '0';

        // 渠道链路
        ['pf' => $pf, 'chain' => $chain, 'promotionGroupId' => $promotionGroupId] = getChainParams();

        // 推广回传
        $promotionFeedback = $params['promotionFeedback'] ?? null;

        $num = $params['num'] ?? 1;
        $num = round($num, 0);
        $unitPrice = $source['unit_price'] ?? null;

        // 计算价格
        $price = bcmul($unitPrice, $num, 2);

        if (is_blank($sourceId)) {
            throw new ValidateException('请选择一个案源');
        }

        $describe = $tradeConfig['name'];

        if (!is_numeric($num)) {
            throw new ValidateException('该案源不能购买');
        }

        if (!is_numeric($price) || $price < 1) {
            throw new ValidateException('该案源不能购买');
        }

        // 暂时没说优惠卷
        $showMoney = $price;
        $totalMoney = $price;
        $payMoney = $totalMoney;

        if ($payMoney < 0.01) {
            throw new ValidateException('订单价格应该大于0');
        }

        $tradeParams = [
            'payMethod' => PAYMENT_CARD,
            'memberId' => $memberId,
            'orderNoPre' => 'S',
            'describe' => $describe,
            'tradeType' => $tradeType,
            'tradeTypeClass' => $tradeTypeClass,
            'sourceId' => $sourceId,
            'showMoney' => $showMoney,
            'totalMoney' => $totalMoney,
            'payMoney' => $payMoney,
            'num' => $num,
            'payStatus' => Trade::UNPAID,
            'payExpTime' => time() + 3600,
            'settleStatus' => Trade::NOTSETTLE,
            'sourceStatus' => Trade::ARY_INVITING,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
            'attach' => [
                'attach' => '',
                'aryOrderId' => $aryOrderId,
                'source' => $source,
                'source_type' => $source_type,
                'buyout' => '0',
                'promotionFeedback' => $promotionFeedback,
            ],
        ];

        $record = $this->tradeDao->insertTrade($tradeParams);

        // 触发订单创建事件
        event('TradeCreated', $record);

        return $record;
    }


    // 完成订单
    public function completionTrade(Trade $trade)
    {
        // 完成购买

        $this->getPromotionCallbackService()->push($trade);

        // 触发订单完成事件
        event('TradeEnded', $trade);

    }

    // 完成退款，收回服务
    public function completionRefundTrade(Trade $trade)
    {

        throw new ValidateException('案源订单没有退款路径');

        return;
    }

    // 已取消支付&订单
    public function canceledTrade(Trade $trade)
    {

        return;
    }

    private function getPromotionCallbackService(): \app\common\service\PromotionCallbackService
    {
        return app(\app\common\service\PromotionCallbackService::class);
    }
}
